#!/usr/bin/python
#
# DESCRIPTION
#
#   This script implements the modify command for the external Linux/UNIX 
#   application.
#
#   The modify command is an input command.  The IDM engine sends a modify 
#   command to the subscriber to request that the external application modify
#   an entry.  The modify command must contain an ASSOCIATION element.
#
#
# VARIABLES
#
#   SRC_DN
#     Specifies the distinguished name of the entry to modify in the name
#     space of eDirectory.
#
#   CLASS_NAME
#     Specifies the base class of the entry being modified.  This attribute
#     is required for modify events.
#
#   EVENT_ID
#     Specifies an identifier to identify a particular instance of the command.
#
#   ASSOCIATION
#     Specifies the unique identifier for the entry in the external
#     application.  This element is required for modify events.
#
#   ADD_<ATTR_NAME>
#     Specifies one or more values to add to <ATTR_NAME>, where <ATTR_NAME> is
#     literally replaced by the name of the attribute being modified.
#
#   REMOVE_<ATTR_NAME>
#     Specifies one or more values to remove to <ATTR_NAME>, where <ATTR_NAME>
#     is literally replaced by the name of the attribute being modified.
#
#   REMOVE_ALL_<ATTR_NAME>
#     Instructs to remove all values associated with <ATTR_NAME>, where 
#     <ATTR_NAME> is literally replaced by the name of the attribute being 
#     modified.
#
#
# REPLY FORMAT
#
#    The receiving application should respond to the modify with a STATUS
#    and an optional STATUS_MESSAGE which can be returned for IDM engine
#    processing and logging facilities.
#
#    The format for returning STATUS and STATUS_MESSAGE are as follows:
#
#      status_<level>("<optional message>")
#
#        <level> may be one of the following values:
#        * success
#        * warning
#        * error
#        * retry
#        * fatal
#
#      Note:  fatal will shutdown the driver, retry will retry the event
#             later on.
#

# include the IDM Library
from idmlib import *
from globals import *

import MySQLdb
import sys

g = GlobalSettings()

logger("debug", "modify.py", " modifying ")
trace(" modify.py ")

class_name = idmgetvar("CLASS_NAME")
mysqlprovuser = idmgetdrvvar("mysqlprovuser");
mysqlprovpw = idmsubgetnamedpassword("mysqlprovpw");

ASSOCIATION = idmgetvar("ASSOCIATION")

# Get database name and host out of the association
(dbname,dbhost,dbport) = ASSOCIATION.split('@')

# Check input validity
if (dbname == ''):
    status_error("Missing database name to delete!")
    sys.exit(0)
if (dbhost == ''):
    status_error("Missing database host!")
    sys.exit(0)
if (dbport == ''):
    status_error("Missing database port!")
    sys.exit(0)

### This will be needed as an int later
dbport = int(dbport)

# Get a Database Connection
try:
    conn = MySQLdb.connect (host = dbhost,
                             user = mysqlprovuser,
                             passwd = mysqlprovpw,
                             port = dbport)

except MySQLdb.Error, e:
    status_error("MYSQL ERROR %d: %s" % (e.args[0], e.args[1]))
    sys.exit (0)
except KeyError:
    status_error("Key Error:  Most likely cause is using an invalid dbhost, or \
    missing privileged user/pass for dbhost")    
    sys.exit (0)
except:
    status_error("An unexpected error occured while trying to connect mysql on: " + dbhost)
    sys.exit(0)

# Make sure the database already exists, then if not, somethings wrong so lets fail.
try:
     cursor = conn.cursor ()
     cursor.execute ("SHOW DATABASES LIKE '" + MySQLdb.escape_string(dbname) + "'");
     if (cursor.rowcount > 0):
       pass # The database is there, we are good to keep going 
     else:
        cursor.close ()
        status_error("Attempting to modify database: (" + dbname + ").  It does not exist!")
        sys.exit(0)

     ### select the mysql administrative database;
     cursor.execute ("USE mysql;")

     ### Walk though REMOVE_GRANTSETS and revoke each.
     dbgrantsets = idmgetvar("REMOVE_GRANTSETS").splitlines(0)

     for value in dbgrantsets:
        (userid,passwd,hostpattern) = value.split('||')
             
        grantstr = 'REVOKE ALL PRIVILEGES ON ' + MySQLdb.escape_string(dbname) + '.* '\
                    + 'FROM ' + MySQLdb.escape_string(userid) + " @'"\
                    + MySQLdb.escape_string(hostpattern) + "';"
             
        # make it happen       
        try:
           cursor.execute (grantstr)
        except MySQLdb.Error, e:
           if (e.args[0] == 1141) or (str(e.args[1]).count('no such grant') > 0):
              # not really a problem...keep going
              pass
           else:
              status_error("MYSQL ERROR %d: %s" % (e.args[0], e.args[1]))
              sys.exit (0)
             
      

     ### Walk through ADD_GRANTSETS and grant each
     dbgrantsets = idmgetvar("ADD_GRANTSETS").splitlines(0)

     for value in dbgrantsets:
        (userid,passwd,hostpattern) = value.split('||')
             
        grantstr = 'GRANT ALL PRIVILEGES ON ' + MySQLdb.escape_string(dbname) + '.* '\
                    + 'TO ' + MySQLdb.escape_string(userid) + " @'"\
                    + MySQLdb.escape_string(hostpattern) + "' IDENTIFIED BY '"\
                    + MySQLdb.escape_string(passwd) + "';"
             
        # make it happen       
        cursor.execute (grantstr)
 

     ### clean up
     cursor.close ()
        
except MySQLdb.Error, e:
    cursor.close ()
    status_error("MYSQL ERROR %d: %s" % (e.args[0], e.args[1]))
    sys.exit (0)

### And we're out
status_success("OK")


